package com.gao.api.gate.quick.proto.http;

import com.gao.api.gate.quick.core.map.IgnoreCaseMultiValueMap;
import com.google.common.collect.ArrayListMultimap;
import org.apache.commons.lang3.StringUtils;

import java.net.URLDecoder;
import java.util.Collection;
import java.util.Objects;
import java.util.Set;
import java.util.StringTokenizer;

public class HttpParams implements Cloneable {
    private final IgnoreCaseMultiValueMap<String> params;

    private HttpParams() {
        this.params = new IgnoreCaseMultiValueMap<>(ArrayListMultimap.create());

    }

    public static HttpParams parse(String paramsString) {
        HttpParams queryParams = new HttpParams();
        if (StringUtils.isBlank(paramsString)) {
            return queryParams;
        }
        StringTokenizer st = new StringTokenizer(paramsString, "&");
        int i;
        while (st.hasMoreTokens()) {
            String s = st.nextToken();
            i = s.indexOf("=");
            // key-value query param
            if (i > 0) {
                String name = s.substring(0, i);
                String value = s.substring(i + 1);
                try {
                    name = URLDecoder.decode(name, "UTF-8");
                    value = URLDecoder.decode(value, "UTF-8");
                }catch (Exception e) {
                    // do nothing
                }
                queryParams.add(name, value);
                // respect trailing equals for key-only params
                if (s.endsWith("=") && StringUtils.isBlank(value)) {
                    //queryParams.setTrailingEquals(name, true);
                }
            }
            // key only
            else if (s.length() > 0) {
                String name = s;
                try {
                    name = URLDecoder.decode(name, "UTF-8");
                }catch (Exception e) {
                    // do nothing
                }
                queryParams.add(name, "");
            }
        }

        return queryParams;
    }


    public void remove(String key) {
        params.removeAll(key);
    }

    public void add(String key,String val){
        params.put(key, val);
    }


    public Collection<String> get(String name) {
        return params.get(name);
    }

    public boolean contains(String name) {
        return params.containsKey(name);
    }

    public void clear()
    {
        params.clear();
    }

    public Set<String> keySet() {
        return params.keySet();
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        params.forEach((key, strings) -> {
            sb.append(key);
            sb.append('=');
            sb.append(strings);
            sb.append('&');
        });
        // Remove trailing '&'.
        if (sb.length() > 0 && '&' == sb.charAt(sb.length() - 1)) {
            sb.deleteCharAt(sb.length() - 1);
        }
        return sb.toString();
    }

    @Override
    protected HttpParams clone()
    {
        HttpParams copy = new HttpParams();
        copy.params.putAll(this.params);
        return copy;
    }


    @Override
    public int hashCode()
    {
        return params.hashCode();
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        HttpParams that = (HttpParams) o;
        return Objects.equals(params, that.params);
    }
}
